package com.sail.redis.util;

import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component
@Slf4j
public class RedissonLockUtil {

    @Autowired
    private RedissonClient redissonClient;

    /**
     * 获取分布式锁(如果业务逻辑执行时间不确定，或者可能较长，建议启用看门狗机制。)
     *
     * @param name     锁的key值
     * @param waitTime 获取锁的最大等待时间
     * @param unit     时间单位
     * @return true: 获取到锁, false: 没有获取到锁
     */
    public boolean getLock(String name, long waitTime, TimeUnit unit) throws InterruptedException {
        RLock lock = redissonClient.getLock(name);
        //没有设置锁释放时间 看门狗机制会自动续期锁的租约时间，避免锁提前释放。锁会在租约时间后自动释放，避免死锁。
        return lock.tryLock(waitTime, unit);
    }

    /**
     * 获取分布式锁 (如果业务逻辑执行时间较短且可控，可以显式设置 leaseTime，避免看门狗机制的开销)
     *
     * @param name      锁的key值
     * @param waitTime  获取锁的最大等待时间
     * @param leaseTime 锁的自动释放时间（超时释放）
     * @param unit      时间单位
     * @return true: 获取到锁, false: 没有获取到锁
     */
    public boolean getLock(String name, long waitTime, long leaseTime, TimeUnit unit) throws InterruptedException {
        RLock lock = redissonClient.getLock(name);
        return lock.tryLock(waitTime, leaseTime, unit);
    }

    /**
     * 解锁分布式锁
     *
     * @param name 锁key值
     */
    public void unLock(String name) {
        RLock lock = redissonClient.getLock(name);
        lock.unlock();
    }
}